package com.enjoyor.soa.traffic.core.tpcms.service.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.enjoyor.soa.traffic.api.dto.tpcms.PassCheckDto;
import com.enjoyor.soa.traffic.core.tpcms.domain.InfoAlarmRedis;
import com.enjoyor.soa.traffic.core.tpcms.domain.InfoAlarmRedisAll;
import com.enjoyor.soa.traffic.core.tpcms.domain.PassApply;
import com.enjoyor.soa.traffic.core.tpcms.domain.PassCard;
import com.enjoyor.soa.traffic.core.tpcms.domain.PassCheck;
import com.enjoyor.soa.traffic.core.tpcms.domain.PassVehicle;
import com.enjoyor.soa.traffic.core.tpcms.domain.RltApplyZone;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IInfoAlarmRedisMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassApplyMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassCardMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassCheckMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IPassVehicleMapper;
import com.enjoyor.soa.traffic.core.tpcms.mapper.IRltApplyZoneMapper;
import com.enjoyor.soa.traffic.core.tpcms.service.IPassCardService;
import com.enjoyor.soa.traffic.core.tpcms.service.IPassCheckService;
import com.enjoyor.soa.traffic.frame.aop.DubboServiceInterceptor;
import com.enjoyor.soa.traffic.frame.logger.IPubLogMapper;
import com.enjoyor.soa.traffic.frame.support.redis.IRedisTool;
import com.enjoyor.soa.traffic.process.service.ProcessService;
import com.enjoyor.soa.traffic.process.vo.ProcessVo;
import com.enjoyor.soa.traffic.util.enums.EnumApplyStatus;
import com.enjoyor.soa.traffic.util.enums.log.LogInfoDic;
import com.enjoyor.soa.traffic.util.helper.ReflectHelper;
import com.enjoyor.soa.traffic.util.helper.TimeHelper;
import com.enjoyor.soa.traffic.util.pojo.Page;

/**
 * 申请单审核信息
 * 
 * @author fzj 2018年5月2日
 */
@Service
@Transactional
public class PassCheckService implements IPassCheckService {

	private static final Logger logger = Logger.getLogger(PassCheckService.class);
    @Autowired
    private IPassCheckMapper passCheckMapper;

    @Autowired
    private IRltApplyZoneMapper rltApplyZoneMapper;

    @Autowired
    private IPassCardMapper passCardMapper;

    @Autowired
    private IPassApplyMapper passApplyMapper;

    @Autowired
    private IPassVehicleMapper passVehicleMapper;

    @Autowired
    private IPubLogMapper pubLogMapper;

    @Reference(timeout = 10000)
    private ProcessService dubboProcessService;

    @Autowired
    private IInfoAlarmRedisMapper infoAlarmRedisMapper;

    @Autowired
    private IRedisTool redisTool;

    @Autowired
    private IPassCardService passCardService;

    @Value("${log.system.name}")
    private String systemName;

    /**
     * 申请单审核
     */
    @SuppressWarnings("unused")
    @Override
    public String insertPassCheck(PassCheckDto passCheckDto, String userName) {
        // 默认审核信息
        String checkId = "C" + TimeHelper.getUniqueString();
        passCheckDto.setCheckId(checkId);
        passCheckDto.setIsDelete("0");
        passCheckDto.setCheckTime(TimeHelper.dateToLongString());
        String userType = passCheckDto.getUserType();
        // detachment为支队，department为秩序科，leader为领导,bigment为大队
        if ("detachment".equals(userType)) {
            passCheckDto.setCheckName("支队审核");
        } else if ("department".equals(userType)) {
            passCheckDto.setCheckName("秩序科审核");
        } else if ("leader".equals(userType)) {
            passCheckDto.setCheckName("领导审核");
        } else if ("bigment".equals(userType)) {
            passCheckDto.setCheckName("大队审核");
        } else {
            passCheckDto.setCheckName("审核");
        }
        PassCheck PassCheckPojo = ReflectHelper.beanToBean(passCheckDto, PassCheck.class);
        String passApplyId = PassCheckPojo.getPassApplyId();
        String checkStatusId = PassCheckPojo.getCheckStatusId();

        // 新增关联禁行线路列表
        String stopRoadIds = passCheckDto.getStopRoadIds();
        String stopRoadNames = passCheckDto.getStopRoadNames();
        if (stopRoadIds != null && stopRoadNames != null && !"".equals(stopRoadIds) && !"".equals(stopRoadNames)) {
            String[] stopRoadIdArr = stopRoadIds.replaceAll(" ", "").split(";");
            String[] stopRoadNameArr = stopRoadNames.replaceAll(" ", "").split(";");
            if (stopRoadIdArr.length == stopRoadNameArr.length) {
                for (int i = 0; i < stopRoadIdArr.length; i++) {
                    RltApplyZone rltApplyZone = new RltApplyZone();
                    rltApplyZone.setRltId(TimeHelper.getUniqueString());
                    rltApplyZone.setCheckId(checkId);
                    rltApplyZone.setStopRoadId(stopRoadIdArr[i]);
                    rltApplyZone.setStopRoadName(stopRoadNameArr[i]);
                    rltApplyZoneMapper.insert(rltApplyZone);
                }
            }
        }

        if (EnumApplyStatus.CHECKPASS.getKey().equals(checkStatusId)) {
            // 新增审核记录
            String statusName = EnumApplyStatus.CHECKPASS.getValue();
            PassCheckPojo.setCheckStatusName(statusName);
            passCheckMapper.insert(PassCheckPojo);
            // 执行流程引擎提交
            ProcessVo processVo = this.submitProcess(passApplyId, userType, "1");
            // 完成流程引擎
            if (processVo.getTaskDefinitionKey() == null && processVo.getResult()) {
                // 判断是否完全通过，通过则修改申请单状态为通过以及生成通行证，否则不修改
                PassApply passApplyPojo = new PassApply();
                passApplyPojo.setPassApplyId(passApplyId);
                passApplyPojo.setUpdateTime(TimeHelper.dateToLongString());
                passApplyPojo.setApplyStatusId(checkStatusId);
                passApplyPojo.setApplyStatusName(statusName);
                int updateNum = passApplyMapper.updateByIdSelective(passApplyPojo);
                // 生成通行证
                PassCard passCardPojo = new PassCard();
                PassApply passApply = passApplyMapper.selectById(passApplyId);
                String takeEffectDate = passApply.getTakeEffectDate();
                String loseEffectDate = passApply.getLoseEffectDate();
                /*int addMonth = 0;
                if ("APPLYTYPE01".equals(passApply.getApplyTypeId())) {
                    addMonth = 1;
                } else if ("APPLYTYPE02".equals(passApply.getApplyTypeId())) {
                    addMonth = 3;
                } else if ("APPLYTYPE03".equals(passApply.getApplyTypeId())) {
                    addMonth = 12;
                }
                try {
                    Date takeDate = TimeHelper.StringToDate(takeEffectDate, "yyyy-MM-dd");
                    Date loseDate = TimeHelper.addMonth(takeDate, addMonth);
                    loseEffectDate = TimeHelper.dateToString(loseDate, "yyyy-MM-dd");
                } catch (ParseException e) {
                    e.printStackTrace();
                }*/
                passCardPojo.setPassApplyId(passApplyId);
                passCardPojo.setTakeEffectDate(takeEffectDate);
                passCardPojo.setLoseEffectDate(loseEffectDate);
                passCardPojo.setExtensionNum("0");
                passCardPojo.setIsDelete("0");
                passCardPojo.setPassStatusId(EnumApplyStatus.UNPRINT.getKey());
                passCardPojo.setPassStatusName(EnumApplyStatus.UNPRINT.getValue());
                passCardPojo.setCreateTime(TimeHelper.dateToLongString());
                Map<String, Object> selectMap = new HashMap<String, Object>();
                selectMap.put("passApplyId", passApplyId);
                List<PassVehicle> passVehicleList = passVehicleMapper.getVehicleList(selectMap);
                
                // 获取redis时段详细信息
                InfoAlarmRedis redisValue = new InfoAlarmRedis();
                List<InfoAlarmRedisAll> detailList = infoAlarmRedisMapper.getAlarmRedisByApply(passApplyId);
                redisValue.setType("1");
                redisValue.setTakeEffectDate(takeEffectDate);
                redisValue.setLoseEffectDate(loseEffectDate);
                // redisValue.setPassApplyId(passApplyId);
                redisValue.setDetailList(detailList);

                String maxPassIdValue = passCardService.getMaxPassCardId();
                String maxPassIdA = "";
                String maxPassIdB = "";
                if (maxPassIdValue == null) {
                    maxPassIdA = TimeHelper.dateToString(new Date(), "yyyy") + "P";
                    maxPassIdB = "0100";
                } else {
                    maxPassIdA = maxPassIdValue.substring(0, 5);
                    maxPassIdB = maxPassIdValue.substring(5);
                }
                
                for (PassVehicle passVehicle : passVehicleList) {
                    // String passCardId = "P" + TimeHelper.getUniqueString();
                    maxPassIdB = this.codeAddOne(maxPassIdB, 4);
                    String passCardId = maxPassIdA + maxPassIdB;
                    String applyVehicleId = passVehicle.getApplyVehicleId();
                    passCardPojo.setPassCardId(passCardId);
                    passCardPojo.setApplyVehicleId(applyVehicleId);
                    passCardMapper.insert(passCardPojo);

                    // 存储redis
                    String key = passVehicle.getLicenseNumber();
                    String vehicleTypeName = passVehicle.getVehicleTypeName();
                    redisValue.setVehicleTypeName(vehicleTypeName);
                    redisTool.setObject(key, redisValue);
                }
                
            }
            // 保存日志
            pubLogMapper.saveNoramlLogInfo(userName, systemName,
                    LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_INSERT.getCode(),
                    String.format(passCheckDto.getCheckName() + ",审核通过:{%s} 操作成功!", new Object[] { passApplyId }),
                    LogInfoDic.LOG_MODULAR_ENUM.PROCESS_MANAGEMENT.getMessage());
        } else if (EnumApplyStatus.CHECKREJECT.getKey().equals(checkStatusId)) {
            // 新增审核记录
            String statusName = EnumApplyStatus.CHECKREJECT.getValue();
            PassCheckPojo.setCheckStatusName(statusName);
            passCheckMapper.insert(PassCheckPojo);
            // 修改申请单状态为不通过
            PassApply passApplyPojo = new PassApply();
            passApplyPojo.setPassApplyId(passApplyId);
            passApplyPojo.setUpdateTime(TimeHelper.dateToLongString());
            passApplyPojo.setApplyStatusId(checkStatusId);
            passApplyPojo.setApplyStatusName(statusName);
            int updateNum = passApplyMapper.updateByIdSelective(passApplyPojo);
            // 保存日志
            pubLogMapper.saveNoramlLogInfo(userName, systemName,
                    LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_INSERT.getCode(),
                    String.format(passCheckDto.getCheckName() + ",审核不通过:{%s} 操作成功!", new Object[] { passApplyId }),
                    LogInfoDic.LOG_MODULAR_ENUM.PROCESS_MANAGEMENT.getMessage());
            // 执行流程引擎提交
            ProcessVo processVo = this.submitProcess(passApplyId, userType, "0");
        }
        return checkId;
    }

    /**
     * 获取审核记录列表信息
     */
    @Override
    public List<PassCheckDto> getPassCheckList(Map<String, Object> map) {
        // 获取申请单基础信息
        List<PassCheck> passCheckList = passCheckMapper.getPassCheckList(map);
        List<PassCheckDto> passCheckDtoList = ReflectHelper.listToList(passCheckList, PassCheckDto.class);
        for (PassCheckDto passCheckDto : passCheckDtoList) {
            Map<String, Object> checkIdMap = new HashMap<String, Object>();
            String checkId = passCheckDto.getCheckId();
            checkIdMap.put("checkId", checkId);
            // 获取申请单关联区域信息
            String stopRoadIds = "";
            String stopRoadNames = "";
            List<RltApplyZone> rltApplyZoneList = rltApplyZoneMapper.getRltApplyZoneList(checkIdMap);
            for (RltApplyZone rltApplyZone : rltApplyZoneList) {
                if (rltApplyZone.getStopRoadId() != null && !"".equals(rltApplyZone.getStopRoadId())) {
                    if (stopRoadIds == "") {
                        stopRoadIds = rltApplyZone.getStopRoadId();
                    } else {
                        stopRoadIds += rltApplyZone.getStopRoadId() + ";";
                    }
                }
                if (rltApplyZone.getStopRoadName() != null && !"".equals(rltApplyZone.getStopRoadName())) {
                    if (stopRoadNames == "") {
                        stopRoadNames += rltApplyZone.getStopRoadName();
                    } else {
                        stopRoadNames += rltApplyZone.getStopRoadName() + ";";
                    }
                }
            }
            // stopRoadIds = stopRoadIds.substring(0, stopRoadIds.length()-1);
            // stopRoadNames = stopRoadNames.substring(0,
            // stopRoadNames.length()-1);
            passCheckDto.setStopRoadIds(stopRoadIds);
            passCheckDto.setStopRoadNames(stopRoadNames);
        }
        return passCheckDtoList;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Page getPassApplyCheckPage(Page page) {
        Page checkPage = passApplyMapper.selectPageInfo(page);
        List<PassApply> passApplyList = (List<PassApply>) checkPage.getResult();
        for (PassApply passApply : passApplyList) {
            String passApplyId = passApply.getPassApplyId();
            ProcessVo processVo = this.getNowProcess(passApplyId);
            // passApplyId
            if ("APPLYSTATUS02".equals(passApply.getApplyStatusId())) {
                if ("bigment".equals(processVo.getTaskDefinitionKey())) {
                    passApply.setApplyStatusId(EnumApplyStatus.WAITCHECK_BIG.getKey());
                    passApply.setApplyStatusName(EnumApplyStatus.WAITCHECK_BIG.getValue());
                } else if ("detachment".equals(processVo.getTaskDefinitionKey())) {
                    passApply.setApplyStatusId(EnumApplyStatus.WAITCHECK_DETACH.getKey());
                    passApply.setApplyStatusName(EnumApplyStatus.WAITCHECK_DETACH.getValue());
                } else if ("department".equals(processVo.getTaskDefinitionKey())) {
                    passApply.setApplyStatusId(EnumApplyStatus.WAITCHECK_DEPART.getKey());
                    passApply.setApplyStatusName(EnumApplyStatus.WAITCHECK_DEPART.getValue());
                } else if ("leader".equals(processVo.getTaskDefinitionKey())) {
                    passApply.setApplyStatusId(EnumApplyStatus.WAITCHECK_LEADER.getKey());
                    passApply.setApplyStatusName(EnumApplyStatus.WAITCHECK_LEADER.getValue());
                } else {
                    passApply.setApplyStatusId(passApply.getApplyStatusId());
                    passApply.setApplyStatusName("待审核异常！");
                }
            }
        }
        checkPage.setResult(passApplyList);
        return checkPage;
    }

    // 数字流水号递增 长度不够补0方法
    public String codeAddOne(String code, int len) {
        Integer intHao = Integer.parseInt(code);
        intHao++;
        String strHao = intHao.toString();
        while (strHao.length() < len) {
            strHao = "0" + strHao;
        }
        return strHao;
    }

    /**
     * 提交流程引擎操作,返回执行后的节点位置
     * 
     * @param passApplyId
     *            申请编号
     * @param userType
     *            提交用户类型 (detachment:支队 ;department:秩序科; leader:领导)
     * @param value
     *            条件参数 值 1，为通过 0，不通过
     * @return ProcessVo 返回当前节点， 任务id、任务标识 、任务名称、任务负责人，业务数据id
     */
    public ProcessVo submitProcess(String passApplyId, String userType, String value) {
        try {
            ProcessVo processVo = dubboProcessService.submitByBuskey_p(passApplyId, userType, "operation", value);
            return processVo;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
    }

    /**
     * 
     * 根据业务数据id，返回信息包括任务id、任务标识 、任务名称、任务负责人，业务数据id
     * 
     * @param passApplyId
     *            申请编号
     * @return ProcessVo 返回一条， 任务id、任务标识 、任务名称、任务负责人，业务数据id
     */
    public ProcessVo getNowProcess(String passApplyId) {
        ProcessVo processVo = dubboProcessService.findTaskId_One(passApplyId);
        return processVo;
    }

}
